from api import models
from rest_framework import serializers
from rest_framework.exceptions import ValidationError


class NewsSerializer(serializers.ModelSerializer):
    image_list = serializers.SerializerMethodField()
    topic_title = serializers.CharField(source='topic.title', read_only=True)  # 写在 read_only_fields 里不生效
    zone_title = serializers.CharField(source='get_zone_display', read_only=True)
    status = serializers.CharField(source='get_status_display', read_only=True)

    class Meta:
        model = models.News
        fields = ['id', 'title', 'url', 'image', 'image_list', 'topic', 'topic_title', 'zone', 'zone_title', 'status',
                  'collect_count', 'recommend_count', 'comment_count']
        read_only_fields = ['collect_count', 'recommend_count', 'comment_count']
        extra_kwargs = {
            'topic': {'write_only': True},
            'image': {'write_only': True},
            'zone': {'write_only': True},
        }

    def get_image_list(self, obj):
        if not obj.image:
            return []
        return obj.image.split(',')

    def validate_topic(self, value):
        if not value:
            return value
        request = self.context.get('request')
        exists = models.Topic.objects.filter(deleted=False, id=value.id, user=request.user).exists()
        if not exists:
            raise ValidationError('话题不存在')
        return value

    def validate_title(self, value):
        url = self.initial_data.get('url', None)
        image = self.initial_data.get('image', None)
        zone_title = self.initial_data.get('zone_title', None)

        if url and image:
            raise ValidationError('请求数据错误')
        if not url and not image and zone_title == '图片':
            raise ValidationError('分区选择错误')
        return value

    def create(self, validated_data):
        request = self.context.get('request')
        # 1. 创建资讯
        new_obj = models.News.objects.create(recommend_count=1, **validated_data)
        # 2. 推荐记录
        models.Recommend.objects.create(
            news=new_obj,
            user=request.user
        )
        return new_obj


class IndexSubTopicSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Topic
        fields = ['id', 'title', 'is_hot']


class IndexSubUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.UserInfo
        fields = ['id', 'username']


class IndexSerializer(serializers.ModelSerializer):
    image_list = serializers.SerializerMethodField()

    collect = serializers.SerializerMethodField()
    recommend = serializers.SerializerMethodField()

    zone = serializers.CharField(source='get_zone_display')
    topic = IndexSubTopicSerializer(read_only=True)
    user = IndexSubUserSerializer(read_only=True)

    class Meta:
        model = models.News
        fields = ['id', 'title', 'url', 'image_list', 'topic', 'zone', 'user', 'collect', 'recommend', 'comment_count']

    def get_image_list(self, obj):
        if not obj.image:
            return []
        return obj.image.split(',')

    def get_collect(self, obj):
        request = self.context.get('request')
        if not request.user:
            return {'count': obj.collect_count, 'has_collect': False}
        exists = models.Collect.objects.filter(user=request.user, news=obj).exists()
        return {'count': obj.collect_count, 'has_collect': exists}

    def get_recommend(self, obj):
        request = self.context.get('request')
        if not request.user:
            return {'count': obj.recommend_count, 'has_recommend': False}
        exists = models.Recommend.objects.filter(user=request.user, news=obj).exists()
        return {'count': obj.recommend_count, 'has_recommend': exists}
